localStorage
或sessionStorage
。Authorization: Bearer <token>
我們用一個常見的測試 API 來模擬登入:
https://reqres.in/api/login
POST
{
"email": "eve.holt@reqres.in",
"password": "cityslicka"
}
{
"token": "QpwL5tke4Pnpja7X4"
}
專案結構
login-demo/
├── index.html
├── style.css
└── script.js
index.html
<!DOCTYPE html>
<html lang="zh-Hant">
<head>
<meta charset="UTF-8">
<title>登入系統 Demo</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>登入系統</h1>
<form id="loginForm">
<div>
<label for="email">Email:</label>
<input type="email" id="email" placeholder="輸入 Email" required>
<span class="error" id="emailError"></span>
</div>
<div>
<label for="password">密碼:</label>
<input type="password" id="password" placeholder="輸入密碼" required>
<span class="error" id="passwordError"></span>
</div>
<button type="submit">登入</button>
</form>
<div id="welcome" style="display:none;">
<h2>🎉 歡迎登入成功!</h2>
<p id="tokenInfo"></p>
<button id="logout">登出</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script src="script.js"></script>
</body>
</html>
style.css
body {
font-family: Arial, sans-serif;
max-width: 400px;
margin: 50px auto;
text-align: center;
}
form div {
margin-bottom: 15px;
}
input {
padding: 8px;
width: 90%;
}
button {
padding: 10px 15px;
cursor: pointer;
}
.error {
color: red;
font-size: 12px;
}
script.js
const loginForm = document.getElementById('loginForm');
const emailInput = document.getElementById('email');
const passwordInput = document.getElementById('password');
const emailError = document.getElementById('emailError');
const passwordError = document.getElementById('passwordError');
const welcomeDiv = document.getElementById('welcome');
const tokenInfo = document.getElementById('tokenInfo');
const logoutBtn = document.getElementById('logout');
// 假登入 API
const API_URL = 'https://reqres.in/api/login';
// 簡單表單驗證
function validateForm() {
let valid = true;
emailError.textContent = '';
passwordError.textContent = '';
if (!emailInput.value.includes('@')) {
emailError.textContent = '請輸入正確的 Email 格式';
valid = false;
}
if (passwordInput.value.length < 6) {
passwordError.textContent = '密碼至少需要 6 位數';
valid = false;
}
return valid;
}
// 登入流程
loginForm.addEventListener('submit', (e) => {
e.preventDefault();
if (!validateForm()) return;
axios.post(API_URL, {
email: emailInput.value,
password: passwordInput.value
})
.then(res => {
const token = res.data.token;
localStorage.setItem('authToken', token);
loginForm.style.display = 'none';
welcomeDiv.style.display = 'block';
tokenInfo.textContent = `登入成功!Token: ${token}`;
})
.catch(err => {
alert('登入失敗,請檢查帳號密碼');
console.error(err);
});
});
// 登出
logoutBtn.addEventListener('click', () => {
localStorage.removeItem('authToken');
welcomeDiv.style.display = 'none';
loginForm.style.display = 'block';
});
📌思考延伸:
localStorage
vscookie
有什麼差異與安全性問題?